<?php


namespace Modules\Admin\Tests\Feature;


use App\Helpers\CodeResponse;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Modules\Admin\Entities\Admin;
use Tests\AdminTestCase;

class AdminControllerTest extends AdminTestCase {
    use RefreshDatabase;

    public function testLogin() {

//        $this->mockConsoleOutput = false;
//        $this->artisan('passport:client', ['--password' => true, '--no-interaction' => true]);
//        $this->artisan('passport:keys', ['--no-interaction' => true]);


        $response = $this->postJson(route('api.admin.login'),
            [
                'username' => $this->admin->username,
                'password' => 'admin',
            ]);

        $response->assertStatus(200)->assertJson(['code' => 0, 'msg' => 'success'])
            ->assertJsonStructure(['data' => ['token_type', 'expires_in', 'access_token', 'refresh_token']]);

    }


    public function testGetInto() {
        $response = $this->getJson(route('api.admin.info'));
        $response->assertStatus(401);
        $response = $this->actingAs($this->admin, 'admin')->getJson(route('api.admin.info'));
//        $response->dump();
        $response->assertStatus(200)->assertJson([
            'code' => 0,
            'msg' => 'success',
            'data' => [
                'username' => $this->admin->username,
                'name' => $this->admin->name,
                'id' => $this->admin->id,
                'created_at' => $this->admin->created_at,
                'updated_at' => $this->admin->updated_at,
            ],
        ])->assertJsonStructure([
            'data' => ['roles'],
        ]);
    }

    public function testUpdateInfo() {

        $url = route('api.admin.info.update');
        //未登录情况下
        $response = $this->putJson($url);
        $response->assertStatus(401);
        //已登录 未传数据
        $response = $this->actingAs($this->admin, 'admin')->putJson($url, ['username' => '', 'name' => '']);

        $response->assertStatus(422)->assertJson(['code' => 0])
            ->assertJsonStructure(['msg'])
            ->assertJsonValidationErrors([
                'username',
                'name',
            ]);
        //正常情况下
        $response = $this->putJson($url,
            [
                'username' => 'admin1',
                'name' => 'admin1',
            ]);
        $response->dump();
        $response->assertStatus(200)->assertJson(['code' => 0, 'msg' => 'success', 'data' => [
            'username' => 'admin1',
            'name' => 'admin1',
            'id' => $this->admin->id,
            'created_at' => $this->admin->created_at,
        ]])->assertJsonStructure(['data' => ['updated_at']]);
    }

    public function testUpdateInfoPassword() {
        $url = route('api.admin.info.password.update');
        //未登录情况下
        $response = $this->putJson($url);
        $response->assertStatus(401);
        //未传字段情况
        $response = $this->actingAs($this->admin, 'admin')->putJson($url);
        $response->assertStatus(422)->assertJson(['code' => 0, 'msg' => '参数验证失败'])
            ->assertJsonValidationErrors([
                'old_password', 'new_password', 'new_password_confirmation',
            ]);

        //两次密码不一致情况
        $response = $this->actingAs($this->admin, 'admin')->putJson($url,
            [
                'old_password' => 'admin12',
                'new_password' => 'admin123',
                'new_password_confirmation' => 'admin1234',
            ]);
        $response->assertStatus(422)->assertJson(['code' => 0, 'msg' => '参数验证失败'])
            ->assertJsonValidationErrors([
                'new_password',
            ]);
        //原始密码错误情况
        $response = $this->actingAs($this->admin, 'admin')->putJson($url,
            [
                'old_password' => 'admin321',
                'new_password' => 'admin1',
                'new_password_confirmation' => 'admin1',
            ]);
        [$code, $message] = CodeResponse::OLD_PASSWORD_FAIL;
        $response->assertStatus(200)->assertJson(['code' => $code, 'msg' => $message]);

        //数据正确情况
        $response = $this->actingAs($this->admin, 'admin')->putJson($url,
            [
                'old_password' => 'admin123',
                'new_password' => 'admin1',
                'new_password_confirmation' => 'admin1',
            ]);
        $response->assertStatus(200)->assertJson(['code' => 0, 'msg' => 'success']);
    }


    public function testIndex() {
        $url = route('api.admin.admin.index',
            [
                'filter[username]' => $this->admin->username,
                'filter[id]' => $this->admin->id,
                'filter[name]' => $this->admin->name,
                'filter[enable_status]' => $this->admin->enable_status,
                'filter[mobile]' => $this->admin->mobile,
                'include' => 'roles.permissions',
            ]);
        //未登录情况下
        $this->notLoggedInTest($url);

        $response = $this->actingAs($this->admin, 'admin')->getJson($url);
//        $response->dump();
        $this->assertJson200($response);
        $response->assertJson([
            'data' => [
                0 => [
                    "id" => $this->admin->id,
                    "username" => $this->admin->username,
                    "name" => $this->admin->name,
                    "enable_status" => $this->admin->enable_status,
                    "mobile" => $this->admin->mobile,
                    "last_login_ip" => $this->admin->last_login_ip,
                    "last_login_time" => $this->admin->last_login_time,
                    //                                          "deleted_at"      => $this->admin->last_login_time,
                ],
            ],
        ])
            ->assertJsonStructure([
                'data' => [
                    [
                        'roles',
                        "created_at",
                        "updated_at",
                    ],
                ],
                'links' => ['first', 'last', 'prev', 'next'],
                'meta' => ['current_page', 'from', 'last_page', 'links' => [], 'path', 'per_page', 'to', 'total'],
            ]);
    }

    public function testAdd() {
        $url = 'api/admin/admins';
        $this->postJson($url)->assertUnauthorized();
        $this->as()->postJson($url,
            [
                'username' => 'test',
                'name' => 'test',
                'mobile' => $this->admin->mobile,
                'password' => 'test123',
            ])->assertCreated();
    }

    public function testUpdate() {
        $url = 'api/admin/admins/1';
        $this->putJson($url)->assertUnauthorized();
        /** @var Admin $admin */
        $admin = Admin::factory()->create();
//        $admin->hasRole()
        $this->as()->putJson($url,
            [
                'username' => $admin->username,
                'name' => 'test',
                'mobile' => $admin->mobile,
            ])->dump()->assertOk();
    }
}
